import React, { useState, useEffect } from "react";
import { Input, Button, Space, Modal, Upload, Select, Flex } from "antd";
import { DownloadOutlined, CloudUploadOutlined } from "@ant-design/icons";
import styles from "./case.module.less";
import { getCase, getTemplate } from "@/api/index";

const { Dragger } = Upload;
const { TextArea } = Input;

const App: React.FC = (props) => {
  const [text, setText] = useState("");
  const [html, setHtml] = useState("");
  const [modify, setModify] = useState(true);
  const [age, setAge] = useState("");
  const [sex, setSex] = useState("");
  const [ModalOpen, setModalOpen] = useState(false);

  const [fileList, setFileList] = useState<UploadFile[]>([]);
  const [uploading, setUploading] = useState(false);
  const [loading, setLoading] = useState(false);
  const config = {
    onRemove: (file) => {
      const index = fileList.indexOf(file);
      const newFileList = fileList.slice();
      newFileList.splice(index, 1);
      setFileList(newFileList);
    },
    beforeUpload: (file) => {
      setFileList([file]);

      return false;
    },
    fileList,
  };

  const handleOk = () => {
    console.log(fileList);
    readFile(fileList[0]);
    setModalOpen(false);
  };

  const readFile = (file) => {
    const reader = new FileReader();
    reader.onload = (e) => {
      console.log(e.target.result);
      update();
      setText(e.target.result);
    };
    reader.readAsText(file);
  };

  const onInput = (e) => {
    setText(e.target.value);
  };
  const handleChange = (e) => {
    setSex(e);
  };

  const getModal = () => {
    getTemplate().then((res) => {
      if (res.code == 200) {
        update();
        setText(res.data.txt);
      }
    });
  };

  const [colors, setColors] = useState({});

  useEffect(() => {
    const obj = props.colors.reduce((p, c) => {
      return { ...p, [c.label]: c.color };
    }, {});
    setColors(obj);
  }, [props]);

  const update = () => {
    document.querySelector(".div2").innerHTML = "";
    setModify(true);
  };

  const run = (e) => {
    setLoading(true);
    const params = {
      age: parseFloat(age),
      sex: sex,
      txt: text,
    };
    props.getParams(params, true);
    getCase(params)
      .then((res) => {
        setLoading(false);
        const keywords = res.data.info_list.entities;

        const { arr, otherline } = findRows(keywords);

        findKeys(arr, otherline, keywords);

        setModify(false);

        props.getRelations(res.data.info_list.relations, false);
      })
      .catch((err) => {
        setLoading(false);
        console.log("错误", err);
      });
  };

  const findKeys = (arr, otherline, keywords) => {
    // 分割文本内容为单个字符
    var characters = text.replace(/[\n]+/g, "\n").split("");

    // 创建用于测量文字位置的 span 元素
    var span = document.createElement("span");
    // span.style.visibility = "hidden";
    // span.style.position = "absolute";
    span.style.whiteSpace = "pre-line";
    span.style.wordWrap = "break-all";

    // 添加 span 元素到页面中
    document.querySelector(".div2").appendChild(span);

    // 遍历每个字符，计算位置
    let res = "";
    for (var i = 0; i < characters.length; i++) {
      const c = keywords.filter((v) => {
        return v.start_offset <= i && i < v.end_offset;
      });
      let cItem;
      if (c.length === 1) {
        cItem = c[0];
      } else if (c.length > 1) {
        let max = 0;
        let maxI = 0;
        c.map((v, i) => {
          if (v.label.length > max) {
            max = v.label.length;
            maxI = i;
          }
        });
        cItem = c[maxI];
      }

      if (cItem) {
        res =
          res +
          "<span style='background: #" +
          colors[cItem.label] +
          "'>" +
          characters[i] +
          "</span>";
      } else {
        if (characters[i] === "\n") {
          res = res + "<span></span>";
        } else {
          res = res + "<span>" + characters[i] + "</span>";
        }
      }
      // 设置 span 元素的文本内容
      if (arr.includes(i)) {
        const n = arr.findIndex((v) => {
          return v === i;
        });
        if (otherline[n] >= 0) {
          for (let j = 0; j <= otherline[n]; j++) {
            res = res + "<br>";
          }
        }
      }
      span.innerHTML = res;
    }

    const parent = document.querySelector(".div2").getBoundingClientRect();

    const l = parent.left;
    const t = parent.top;

    const increase = [];

    let all = 0;
    otherline.map((v) => {
      all = all + v;
      increase.push(all);
    });
    for (let i = 0; i < keywords.length; i++) {
      const p = document.createElement("span");
      p.innerText = keywords[i].label;
      p.style.display = "flex";
      p.style.flexDirection = "row-reverse";
      p.style.alignItems = "center";
      p.style.position = "absolute";
      p.style.fontSize = "12px";
      p.style.top =
        keywords[i].top +
        20 * increase[keywords[i].line - 1] +
        20 * keywords[i].markline +
        "px";
      p.style.left = keywords[i].left + "px";
      const icon = document.createElement("div");
      icon.style.width = "4px";
      icon.style.height = "4px";
      icon.style.marginRight = "4px";
      icon.style.background = "#" + colors[keywords[i].label];
      icon.style.borderRadius = "50%";
      p.appendChild(icon);
      document.querySelector(".div2").appendChild(p);
    }
    // 移除用于测量的 span 元素
    return arr;
  };

  const findRows = (keywords) => {
    // 分割文本内容为单个字符
    let characters = text.replace(/[\n]+/g, "\n").split("");

    // 创建用于测量文字位置的 span 元素
    var span = document.createElement("span");
    span.className = "child";
    // span.style.visibility = "hidden";
    // span.style.position = "absolute";
    span.style.whiteSpace = "pre-line";
    span.style.wordWrap = "break-all";

    // 添加 span 元素到页面中
    document.querySelector(".div2").appendChild(span);

    const l = document.querySelector(".div2").getBoundingClientRect().left;
    const t = document.querySelector(".div2").getBoundingClientRect().top;

    // 遍历每个字符，计算位置
    let res = "";
    // let arr = [];
    for (let i = 0; i < characters.length; i++) {
      // if (characters[i] === '/n') {
      //   console.log(true);
      // }
      // 设置 span 元素的文本内容
      if (characters[i] === "\n") {
        res = res + "<br>";
      } else {
        res = res + "<span>" + characters[i] + "</span>";
      }
      span.innerHTML = res;
    }

    // 移除用于测量的 span 元素
    const spans = document.querySelector(".child")?.childNodes;

    let h = 0;
    let arr = [];
    for (let i = 0; i < spans.length; i++) {
      if (spans[i].tagName === "SPAN") {
        const item = spans[i].getBoundingClientRect();
        if (item.top - t > h) {
          arr.push(i - 1);
          h = item.top - t;
        }
      }
    }

    for (let i = 0; i < keywords.length; i++) {
      const line = arr.findIndex((u) => {
        return keywords[i].start_offset < u + 1;
      });
      if (line !== -1) {
        keywords[i]["line"] = line;
      } else {
        keywords[i]["line"] = arr.length;
      }
      let s = spans[keywords[i].start_offset].getBoundingClientRect();
      // console.log(spans[keywords[i].start_offset].innerHTML);
      const p = document.createElement("span");
      p.innerText = keywords[i].label;
      p.style.position = "absolute";
      p.style.top = s.top - t + "px";
      keywords[i].top = s.top - t;
      keywords[i].left = s.left - l;
      p.style.left = s.left - l + "px";
      const icon = document.createElement("div");
      icon.style.width = "4px";
      icon.style.height = "4px";
      icon.style.marginRight = "4px";
      icon.style.background = "#" + colors[keywords[i].label];
      icon.style.borderRadius = "50%";
      p.appendChild(icon);
      document.querySelector(".div2").appendChild(p);
      let dom = p.getBoundingClientRect();
      keywords[i].width = dom.width;
      if (i === 0 || keywords[i].line !== keywords[i - 1].line) {
        keywords[i]["markline"] = 1;
      } else {
        if (keywords[i].left >= keywords[i - 1].left + keywords[i - 1].width) {
          keywords[i]["markline"] = 1;
        } else {
          if (keywords[i - 1].markline === 1) {
            if (
              i > 1 &&
              keywords[i].line === keywords[i - 2].line &&
              keywords[i].left < keywords[i - 2].left + keywords[i - 2].width
            ) {
              if (keywords[i - 2].markline === 2) {
                keywords[i].markline = 3;
              } else {
                keywords[i].markline = 2;
              }
            } else {
              keywords[i].markline = 2;
            }
          } else if (keywords[i - 1].markline === 2) {
            if (
              i > 1 &&
              keywords[i].line === keywords[i - 2].line &&
              keywords[i].left < keywords[i - 2].left + keywords[i - 2].width
            ) {
              keywords[i].markline = 3;
            } else {
              keywords[i].markline = 1;
            }
          } else {
            keywords[i].markline = 1;
          }
        }
      }
    }
    const otherline = new Array(arr.length).fill(0);
    keywords.map((v) => {
      if (v.line && otherline[v.line - 1] < v.markline) {
        // otherline.splice((v.line - 1), 1, v.markline)
        otherline[v.line - 1] = v.markline;
      }
    });
    otherline.unshift(0);
    if (arr[arr.length - 1] !== spans?.length) {
      arr.push(spans.length);
    }
    document.querySelector(".div2").innerHTML = "";
    console.log(arr);
    console.log(keywords);
    console.log(otherline);
    return { arr, otherline };
  };

  return (
    <>
      <div className={styles.case}>
        <div className={styles.title}>
          <div className={styles.left}>
            <div className={styles.icon}></div>
            病历内容
          </div>
          <div className={styles.right}>
            <Space>
              <Button className={styles.useModal} onClick={getModal}>
                调用模板
              </Button>
              <Button
                icon={<DownloadOutlined />}
                onClick={() => setModalOpen(true)}
              >
                导入
              </Button>
            </Space>
          </div>
        </div>
        <div className={styles.form}>
          <div className={styles.row}>
            <div className={styles.label}>年龄</div>
            <Input
              className={styles.input}
              value={age}
              onInput={(e) => setAge(e.target.value.replace(/[^0-9]/g, ""))}
              placeholder="请输入患者年龄"
            />
            <div className={styles.label}>性别</div>
            <Select
              placeholder="请选择患者性别"
              style={{ width: 210 }}
              onChange={handleChange}
              options={[
                { value: "男", label: "男" },
                { value: "女", label: "女" },
              ]}
            />
          </div>
        </div>
        <div className={styles.content}>
          <TextArea
            style={{ visibility: modify ? "visible" : "hidden" }}
            autoSize={true}
            value={text}
            className={styles.textarea}
            rows={15}
            onInput={onInput}
            placeholder="请输入"
            maxlength={512}
          />
          <div
            style={{ visibility: modify ? "hidden" : "visible" }}
            className={"div2 " + styles.div}
          ></div>
          {/* <div
            className={"div " + styles.div}
            dangerouslySetInnerHTML={{ __html: html }}
          ></div> */}
          {/* <div className={"div3 " + styles.div}></div> */}
          <div className={styles.footer}>
            <Space>
              <Button type="default" onClick={update}>
                编辑
              </Button>
              <Button disabled={!modify} loading={loading} type="primary" onClick={run}>
                运行
              </Button>
            </Space>
          </div>
        </div>
      </div>
      <Modal
        title="导入"
        open={ModalOpen}
        onOk={handleOk}
        okText="确定"
        cancelText="取消"
        onCancel={() => setModalOpen(false)}
      >
        {/* <div className={styles.upload_body}> */}
        <Dragger {...config}>
          <p className="ant-upload-drag-icon">
            <CloudUploadOutlined />
          </p>
          <p className={styles.upload_text}>
            将文件拖到此处，或<span>点击上传</span>
          </p>
          <p className={styles.upload_hint}>
            支持单个txt格式文件上传。严禁上传包含色情、暴力、反动等相关
            违法信息的文件。
          </p>
        </Dragger>
        {/* </div> */}
      </Modal>
    </>
  );
};

export default App;
